package com.wei.chatroom.controller;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.wei.chatroom.component.OnlineUserManger;
import com.wei.chatroom.model.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.socket.CloseStatus;
import org.springframework.web.socket.TextMessage;
import org.springframework.web.socket.WebSocketSession;
import org.springframework.web.socket.handler.TextWebSocketHandler;

import java.io.IOException;
import java.util.List;

/**
 * @projectName: java_chatroom
 * @package: com.wei.chatroom.controller
 * @className: WebSocketController
 * @author: weiJiang
 * @description: 转发消息使用的websocket,需要维护用户和websocket的映射关系（一个用户需要一个对应的websocket用于中转数据）
 * @date: 2025/9/30 下午4:48
 * @version: 1.0
 */

@Component
public class WebSocketController extends TextWebSocketHandler {

    @Autowired
    private OnlineUserManger onlineUserManger;

    private final ObjectMapper objectMapper=new ObjectMapper();//转json用的

    @Autowired
    private MessageSessionMapper messageSessionMapper;

    @Autowired
    private MessageMapper messageMapper;

    private void transferMessage(User fromUser, MessageRequest req) throws IOException {
        //构造待转发的相应对象
        MessageResponse resp=new MessageResponse();
        resp.setType("message");
        resp.setFromId(fromUser.getUserId());
        resp.setFromName(fromUser.getUsername());
        resp.setSessionId(req.getSessionId());
        resp.setContent(req.getContent());

        //把java对象转为string
        String respJson=objectMapper.writeValueAsString(resp);
        System.out.println("转发对象"+respJson);

        //根据请求的sessionId获取要转发的用户,包括自己
        List<Friend> friends=messageSessionMapper.getFriendsBySessionId(req.getSessionId(), fromUser.getUserId());
        Friend mySelf=new Friend();
        mySelf.setFriendId(fromUser.getUserId());
        mySelf.setFriendName(fromUser.getUsername());

        //遍历朋友，并发送相应消息，还是要给自己发一个
        for(Friend friend:friends){
            WebSocketSession webSocketSession=onlineUserManger.getSession(friend.getFriendId());

            if(webSocketSession==null){
                continue;//不在线不发送
            }

            //需要进行包装
            webSocketSession.sendMessage(new TextMessage(respJson));
        }

        //转发的消息还需要存入数据库，后续用户下线后，上线了就能看到消息，没有存就看不到了！
        Message message=new Message();
        message.setFromId(fromUser.getUserId());
        message.setSessionId(req.getSessionId());
        message.setContent(req.getContent());
        //自动主键和日期在sql中自动实现

        messageMapper.add(message);

    }

    @Override
    public void afterConnectionEstablished(WebSocketSession session) throws Exception {
        super.afterConnectionEstablished(session);
        System.out.println("webSocket连接成功");
        //获取网页会话属性，注册拦截器是前提
        //直接获取网页会话中user这个属性的内容
        //getAttributes返回的是一个map
        User user=(User) session.getAttributes().get("user");
        if(user==null){
            return;
        }
        System.out.println("获取到的用户id:"+user.getUserId());
        onlineUserManger.online(user.getUserId(),session);
    }

    //关键方法,转发消息方法
    @Override
    protected void handleTextMessage(WebSocketSession session, TextMessage message) throws Exception {
        super.handleTextMessage(session, message);
        System.out.println("webSocket收到消息" + message.toString());

        User user=(User) session.getAttributes().get("user");
        if(user==null){
            System.out.println("消息转发时没有找到用户");
            return;
        }

        //针对请求进行解析,先把json转换为对象
        MessageRequest req=objectMapper.readValue(message.getPayload(),MessageRequest.class);

        if(req.getType().equals("message")){
            transferMessage(user,req);
        }else{
            System.out.println("message type有误在handleTextMessage");
        }

    }

    @Override
    public void afterConnectionClosed(WebSocketSession session, CloseStatus status) throws Exception {
        super.afterConnectionClosed(session, status);
        System.out.println("webSocket连接关闭"+status.toString());

        User user=(User) session.getAttributes().get("user");
        if(user==null){
            return;
        }
        onlineUserManger.offline(user.getUserId(),session);
    }

    @Override
    public void handleTransportError(WebSocketSession session, Throwable exception) throws Exception {
        super.handleTransportError(session, exception);
        System.out.println("webSocket连接异常"+exception.toString());

        User user=(User) session.getAttributes().get("user");
        if(user==null){
            return;
        }
        onlineUserManger.offline(user.getUserId(),session);
    }
}
